# -*- coding: utf-8 -*-
"""
Created on Wed Feb 16 10:32:58 2022

@author: Apple
"""

import os
import sys
from PyQt5.QtWidgets import (QAbstractItemView,QMainWindow,QWidget,QTableWidget,QHBoxLayout,QMessageBox,QApplication,QTableWidgetItem,QHeaderView)
from main_window import Ui_MainWindow
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
import pandas as pd
import numpy as np
import math
import matplotlib.pyplot as plt
import CW_saving
import re


class MainWindow(QMainWindow):
    def __init__(self,parent=None):
        super(MainWindow,self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        
        # 初始化表格1
        tw1 = self.ui.tableWidget1
        tw1.setRowCount(1)
        tw1.setColumnCount(3)
        tw1.setHorizontalHeaderLabels(['编号','X坐标','Y坐标'])
        tw1.setEditTriggers(QTableWidget.CurrentChanged)
        for i in range(3):
            newItem = QTableWidgetItem('')
            newItem.setTextAlignment(Qt.AlignCenter)
            tw1.setItem(0,i,newItem)
            
        # 初始化表格2
        tw2 = self.ui.tableWidget2
        tw2.setRowCount(3)
        tw2.setColumnCount(3)
        tw2.setEditTriggers(QTableWidget.CurrentChanged)
        for i in range(3):
            for j in range(3):
                newItem = QTableWidgetItem('')
                newItem.setTextAlignment(Qt.AlignCenter)
                tw2.setItem(i,j,newItem)
        
        # 将按键与函数绑定
        self.ui.actionopenfile.triggered.connect(self.openfile)
        self.ui.actionversion.triggered.connect(self.showversion)
        self.ui.btn1.clicked.connect(lambda:self.inputnum(1)) # 利用lambda函数来调用定义函数中的对应功能
        self.ui.btn2.clicked.connect(lambda:self.inputnum(2))
        self.ui.btn1_1.clicked.connect(lambda:self.newrow(tw1))
        self.ui.btn2_1.clicked.connect(lambda:self.newrow(tw2))
        self.ui.btn2_2.clicked.connect(lambda:self.newcol(tw2))
        self.ui.btn1_2.clicked.connect(lambda:self.delrow(tw1))
        self.ui.btn2_3.clicked.connect(lambda:self.delrow(tw2))
        self.ui.btn2_4.clicked.connect(lambda:self.delcol(tw2))
        self.ui.btn1_3.clicked.connect(lambda:self.cleartable(1))
        self.ui.btn2_5.clicked.connect(lambda:self.cleartable(2))
        self.ui.btn1_4.clicked.connect(lambda:self.savedata(tw1))
        self.ui.btn2_6.clicked.connect(lambda:self.savedata(tw2))
        self.ui.btn3_1.clicked.connect(self.draw_graph)
        self.ui.btn3_2.clicked.connect(lambda:self.clearGraph(self.ui.label_pic1))
        self.ui.btn4_1.clicked.connect(self.read_dismat)
        self.ui.btn4_2.clicked.connect(lambda:self.cleartable(3))
        self.ui.btn5_1.clicked.connect(self.runCW)
        self.ui.btn5_2.clicked.connect(lambda:self.cleartable(4))
        self.ui.btn6_1.clicked.connect(self.draw_route)
        self.ui.btn6_2.clicked.connect(lambda:self.clearGraph(self.ui.label_pic2))
        
    # 打开本地文件
    def openfile(self):
        path = os.getcwd() 
        os.startfile(path)
    
    # 展示当前版本
    def showversion(self):
        QMessageBox.about(self, '关于', '当前版本为 V1.0 ')
    
    # 输入站点个数
    def inputnum(self,model):
        if model == 1:
            num = self.ui.lineEdit1.text()
            if num.isdigit() != True :
                print('Please input an *integer*')
                QMessageBox.about(self, '警告', '请输入一个正整数')
                return
            tw1 = self.ui.tableWidget1
            tw1.setRowCount(int(num))
            for i in range(int(num)):
                for j in range(3):
                    newItem = QTableWidgetItem('')
                    newItem.setTextAlignment(Qt.AlignCenter)
                    tw1.setItem(i,j,newItem)
        elif model == 2:
            num = self.ui.lineEdit2.text()
            if num.isdigit() != True :
                print('Please input an *integer*')
                QMessageBox.about(self, '警告', '请输入一个正整数')
                return
            tw2 = self.ui.tableWidget2
            tw2.setRowCount(int(num))
            tw2.setColumnCount(int(num))
            for i in range(int(num)):
                for j in range(int(num)):
                    newItem = QTableWidgetItem('')
                    newItem.setTextAlignment(Qt.AlignCenter)
                    tw1.setItem(i,j,newItem)
    
    # 新增一行
    def newrow(self,tw):
        tableWidget = tw
        numrow = tableWidget.rowCount()
        numcol = tableWidget.columnCount()
        tableWidget.insertRow(numrow)
        for i in range(numcol):
            newItem = QTableWidgetItem('')
            newItem.setTextAlignment(Qt.AlignCenter)
            tableWidget.setItem(numrow,i,newItem)
    
    # 新增一列
    def newcol(self,tw):
        tableWidget = tw
        numrow = tableWidget.rowCount()
        numcol = tableWidget.columnCount()
        tableWidget.insertColumn(numcol)
        for i in range(numrow):
            newItem = QTableWidgetItem('')
            newItem.setTextAlignment(Qt.AlignCenter)
            tableWidget.setItem(i,numcol,newItem)
    
    # 删除一行
    def delrow(self,tw):

        tableWidget = tw
        numrow = tableWidget.rowCount()
        numcol = tableWidget.columnCount()
        if numrow == 1:
            tableWidget.removeRow(0)
            tableWidget.insertRow(0)
            for i in range(numcol):
                newItem = QTableWidgetItem('')
                newItem.setTextAlignment(Qt.AlignCenter)
                tableWidget.setItem(0,i,newItem)            
        else:
            tableWidget.removeRow(numrow-1)
    
    # 删除一列
    def delcol(self,tw):

        tableWidget = tw
        numrow = tableWidget.rowCount()
        numcol = tableWidget.columnCount()
        if numcol == 1:
            tableWidget.removeColumn(0)
            tableWidget.insertColumn(0)
            for i in range(numrow):
                newItem = QTableWidgetItem('')
                newItem.setTextAlignment(Qt.AlignCenter)
                tableWidget.setItem(i,0,newItem)            
        else:
            tableWidget.removeColumn(numcol-1)
    
    # 清空表格内容
    def cleartable(self,model):
        
        if model == 1:
            title = ['编号','X坐标','Y坐标']
            tw1 = self.ui.tableWidget1
            tw1.clear()
            tw1.setRowCount(1)
            tw1.setColumnCount(3)
            for i in range(3):
                newItem = QTableWidgetItem('')
                newItem.setTextAlignment(Qt.AlignCenter)
                tw1.setItem(0,i,newItem)
            
            tw1.setHorizontalHeaderLabels(title)
            tw1.setEditTriggers(QTableWidget.CurrentChanged)
        if model == 2:
            tw2 = self.ui.tableWidget2
            tw2.setRowCount(3)
            tw2.setColumnCount(3)
            tw2.setEditTriggers(QTableWidget.CurrentChanged)
            for i in range(3):
                for j in range(3):
                    newItem = QTableWidgetItem('')
                    newItem.setTextAlignment(Qt.AlignCenter)
                    tw2.setItem(i,j,newItem)
        if model == 3:
            tw3 = self.ui.tableWidget3
            tw3.setRowCount(0)
            tw3.setColumnCount(0)
        if model == 4:
            tw4 = self.ui.tableWidget4
            tw4.setRowCount(0)
            tw4.setColumnCount(0)
            
    
    # 保存当前输入
    def savedata(self,tw):
        tableWidget = tw
        numrow = tableWidget.rowCount()
        numcol = tableWidget.columnCount()
        listall = []
        for i in range(numrow):
            listcol = []
            for j in range(numcol):
                data = tableWidget.item(i,j).text()
                if data =='':
                    QMessageBox.about(self, '警告', '请输入完整数据')
                    return
                else:
                    listcol.append(data)
            listall.append(listcol)
        # print(listall)
        path = os.getcwd() + r'\Data\testdata.csv'
        # print(path)
        test = pd.DataFrame(data = listall)
        test.to_csv(path,index=0)
        QMessageBox.about(self, '完成', '保存成功')    
    
    # 读取距离矩阵
    def read_dismat(self):
        
        tableWidget = self.ui.tableWidget3
        data = pd.read_csv(r'Data\testdata.csv')
        Data = data.iloc[:,:].values.tolist() # 转换为list
        df = pd.DataFrame(columns=data.iloc[:,0],index=data.iloc[:,0])
        
        for i in range(len(Data)):
            for j in range(len(Data)):
                df.iloc[i,j]=f'{format(math.sqrt(pow(Data[i][1]-Data[j][1],2)+pow(Data[i][2]-Data[j][2],2)),".3f")}'
        
        df.to_excel(r'Data/dismat.xlsx')
        # print(df)
        tableWidget.setRowCount(len(df))
        tableWidget.setColumnCount(len(df))
        tableWidget.setHorizontalHeaderLabels(list(data.iloc[:,0]))
        tableWidget.setVerticalHeaderLabels(list(data.iloc[:,0]))
        tableWidget.setEditTriggers(QTableWidget.CurrentChanged)
        for i in range(len(df)):
            for j in range(len(df)):
                newItem = QTableWidgetItem(df.iloc[i,j])
                newItem.setTextAlignment(Qt.AlignCenter)
                tableWidget.setItem(i,j,newItem)
    
    # 生成坐标图片
    def draw_graph(self):
        data = pd.read_csv(r'Data\testdata.csv')
        label = list(data.iloc[:,0])
        x = list(data.iloc[:,1])
        y = list(data.iloc[:,2])
        
        plt.xlabel('X')
        plt.ylabel('Y')
        
        plt.scatter(x, y)
        for i in zip(label,zip(x,y)):
            plt.annotate(i[0], xy=i[1], xytext=(-5, 5), textcoords='offset points')
        plt.savefig('test.jpg',dpi=300)
        
        pic = QPixmap('test.jpg')
        self.ui.label_pic1.setPixmap(pic)
        self.ui.label_pic1.setScaledContents(True)
        
    # 清除图片
    def clearGraph(self,pic):
        pic.clear()
    
    def runCW(self):
        file_name = r'Data\dismat.xlsx'
        data = CW_saving.read_excel(file_name)
        label = list(data.index)
        best_route = []
        best_value = 9999999999
        for i in label:
            route_express,route_dis = CW_saving.main(i,file_name)
            # print(route_express)
            if route_dis < best_value:
                best_value = route_dis
                best_route = route_express
        
        route = best_route[0]
        for i in best_route[1:]:
            route += ">>" + i
        
        pd.DataFrame(data = [route,best_value]).to_csv(r'Data/finaldata.csv',index = 0)
        
        # print(best_route)
        # print(best_value)
        
        tw4 = self.ui.tableWidget4
        tw4.setRowCount(2)
        tw4.setColumnCount(1)
        tw4.setVerticalHeaderLabels(['运输路线','路线总长度'])
        tw4.setHorizontalHeaderLabels(['方案输出'])
        tw4.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
        
        newItem = QTableWidgetItem(route)
        newItem.setTextAlignment(Qt.AlignCenter)
        tw4.setItem(0,0,newItem)
        
        newItem = QTableWidgetItem(str(best_value))
        newItem.setTextAlignment(Qt.AlignCenter)
        tw4.setItem(1,0,newItem)
        
    # 生成坐标图片
    def draw_route(self):
        data = pd.read_csv(r'Data\testdata.csv')
        label = list(data.iloc[:,0])
        x = list(data.iloc[:,1])
        y = list(data.iloc[:,2])
        
        plt.xlabel('X')
        plt.ylabel('Y')
        
        plt.scatter(x, y)
        for i in zip(label,zip(x,y)):
            plt.annotate(i[0], xy=i[1], xytext=(-5, 5), textcoords='offset points')
        
        Data = pd.read_csv(r'Data\finaldata.csv')
        df = Data.iloc[0,0]
        df1 = list(re.sub('>>','',df))
        df2 = []
        while len(df1) != 1:
            df2.append([df1[0],df1[1]])
            del df1[0]
        
        X = []
        Y = []
        
        for i in range(len(df2)):
            for j in range(len(label)):
                if df2[i][0] == label[j]:
                    X.append([x[j],y[j]])
                elif df2[i][1] == label[j]:
                    Y.append([x[j],y[j]])
        
        x1 = []
        y1 = []
        for i in zip(X,Y):
            x1.append([i[0][0],i[1][0]])
            y1.append([i[0][1],i[1][1]])
        
        for i in range(len(x1)):
            plt.plot(x1[i], y1[i], color='r')
            
        plt.savefig('route.jpg',dpi=300)
        
        pic = QPixmap('route.jpg')
        self.ui.label_pic2.setPixmap(pic)
        self.ui.label_pic2.setScaledContents(True)

if __name__=="__main__":
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())